package com.cdivtc.management.aspect;

import com.cdivtc.management.pojo.Result;
import com.cdivtc.management.pojo.SysLog;
import com.cdivtc.management.service.LogSever;
import com.cdivtc.management.service.RequestServer;
import com.cdivtc.management.utils.JwtUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Date;


/**
 * @author Promise
 * @createTime 2018年12月18日 下午9:33:28
 * @description 切面日志配置
 */
@Aspect
@Component
public class LogAsPect {

    private final static Logger log = org.slf4j.LoggerFactory.getLogger(LogAsPect.class);

    @Autowired
    private HttpServletRequest request;
    @Autowired
    private HttpServletResponse response;
    @Autowired
    private RequestServer requestServer;
    @Autowired
    private LogSever logSever;
    private String authorization;
    private SysLog sysLog;

    //表示匹配带有自定义注解的方法
    @Pointcut("@annotation(com.cdivtc.management.aspect.Log)")

    public void pointcut() {
    }

    @Around("pointcut()")
    public Object around(ProceedingJoinPoint point) throws IOException {
        Object result = null;
        long beginTime = System.currentTimeMillis();

        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();
        // 请求的类名
        String className = point.getTarget().getClass().getName();
        // 请求的方法名
        String methodName = signature.getName();
        sysLog = new SysLog();

        sysLog.setOperationName(method.getAnnotation(Log.class).value());
        sysLog.setClazzName(className);
        sysLog.setMethodName(methodName);


        try {
            authorization = ((HttpServletRequest) request).getHeader("Authorization");


            if (JwtUtil.verify(authorization)) {
                result = point.proceed();
                long endTime = System.currentTimeMillis();
                insertLog(point, endTime - beginTime, method);
            } else {
                sysLog.setOperationType("失败");
                sysLog.setErrorMessage("身份认证失败");
                logSever.addSysLog(sysLog, request, new Date().getTime() - beginTime);
                requestServer.SendReresponse(response, new Result().error("身份认证失败"));

            }
        } catch (Throwable e) {
            sysLog.setOperationType("失败");
            sysLog.setErrorMessage(e.getMessage());
            logSever.addSysLog(sysLog, request, new Date().getTime() - beginTime);
            requestServer.SendReresponse(response, new Result().error(e.getMessage()));
            e.printStackTrace();
        }
        return result;
    }

    private void insertLog(ProceedingJoinPoint point, long time, Method method) {


        Log userAction = method.getAnnotation(Log.class);
        if (userAction != null) {
            // 注解上的描述
            sysLog.setOperationName(userAction.value());
        }
        String username = JwtUtil.getUsername(authorization);
//       这个username 为user中的id
        sysLog.setOperationType("成功");
        String args = Arrays.toString(point.getArgs());
        sysLog.setParameter(args);
        System.out.println("username = " + username);
        sysLog.setOperationUsername(username);
        logSever.addSysLog(sysLog, request, time);
//        sysLogService.insertLog(sys_log);
    }


}